﻿using System;
using System.Collections.Generic;
using SCOM = System.Collections.ObjectModel;

namespace Needle.Utils.Collections
{
    /// <summary>
    /// A keyed collection that uses a converter to convert from item to key.
    /// </summary>
    public class KeyedCollection<TKey, TItem> : SCOM.KeyedCollection<TKey, TItem>  
    {

        private Converter<TItem, TKey> _ItemToKey;
        /// <summary>
        /// Creates a new instance
        /// </summary>
        /// <param name="itemToKey">a converter to convert from item to key.</param>
        public KeyedCollection(Converter<TItem, TKey> itemToKey)
        {
            Ensure.NotNull(itemToKey, "itemToKey");
            _ItemToKey = itemToKey;
        }

        /// <summary>
        /// Creates a new instance
        /// </summary>
        public KeyedCollection(Converter<TItem, TKey> itemToKey, IEqualityComparer<TKey> keyComparer)
            : base(keyComparer)
        {
            Ensure.NotNull(itemToKey, "itemToKey");
            _ItemToKey = itemToKey;
        }

        /// <summary>
        /// Creates a new instance
        /// </summary>
        public KeyedCollection(Converter<TItem, TKey> itemToKey, IEqualityComparer<TKey> keyComparer, int dictionaryCreationThreshold)
            : base(keyComparer, dictionaryCreationThreshold)
        {
            Ensure.NotNull(itemToKey, "itemToKey");
            _ItemToKey = itemToKey;
        }
        /// <summary>
        /// convert from item to key.
        /// </summary>
        protected override TKey GetKeyForItem(TItem item)
        {
            return _ItemToKey(item);
        }
        /// <summary></summary>
        public bool TryGetValue(TKey key, out TItem item)
        {
            if (Dictionary != null)
                return Dictionary.TryGetValue(key, out item);
            if (Contains(key))
            {
                item = this[key];
                return true;
            }
            item = default(TItem);
            return false;
        }

    }
}
